using System;
using System.Security.Principal;
using Firestarter.Test.Base;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.BO;
using Habanero.Util;
using NUnit.Framework;
using Rhino.Mocks;

namespace FireStarterModeller.Test.BO
{
    [TestFixture]
    public class TestTransactionLogger
    {
        [TestFixtureSetUp]
        public void SetupTestFixture()
        {
            TestUtilsDomain.SetupFixture();
        }

        [SetUp]
        public void SetupTest()
        {
            TestUtilsDomain.SetupTest();
        }

        [Test]
        public void Test_Construction()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            Transactionlogger transactionlogger = new Transactionlogger();
            //---------------Test Result -----------------------
            Assert.IsInstanceOf(typeof (ITransactionLogger), transactionlogger);
        }

        [Test]
        public void Test_GetCurrentDirtyTransactionLogEntry_ShouldReturnTransactionLogBO()
        {
            //---------------Set up test pack-------------------
            Transactionlogger transactionlogger = new Transactionlogger();
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            IBusinessObject currentDirtyTransactionLogEntry = transactionlogger.GetCurrentDirtyTransactionLogEntry
                (dmClass);
            //---------------Test Result -----------------------
            Assert.IsNotNull(currentDirtyTransactionLogEntry);
            Assert.AreNotSame(dmClass, currentDirtyTransactionLogEntry);
            Assert.IsInstanceOf(typeof (TransactionLogEntry), currentDirtyTransactionLogEntry);
        }

        [Test]
        public void Test_GetCurrentDirtyTransactionLogEntry_WhenNewBo_ShouldBeCorrectTransactionLogEntry()
        {
            //---------------Set up test pack-------------------
            Transactionlogger transactionlogger = new Transactionlogger();
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            string dirtyXml = dmClass.DirtyXML;
            string userName = TestUtilsShared.GetRandomString();
            SetupMockSecurityController(userName);
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            IBusinessObject currentDirtyTransactionLogEntry = transactionlogger.GetCurrentDirtyTransactionLogEntry
                (dmClass);
            //---------------Test Result -----------------------
            TransactionLogEntry transactionLogEntry = currentDirtyTransactionLogEntry as TransactionLogEntry;
            Assert.IsNotNull(transactionLogEntry);
            Assert.AreEqual("Added", transactionLogEntry.CRUDAction);
            Assert.AreEqual(dirtyXml, transactionLogEntry.DirtyXML.ToString());
            Assert.AreEqual(dmClass.ToString(), transactionLogEntry.BusinessObjectToString);
            Assert.AreEqual(typeof (DMClass).ToString(), transactionLogEntry.BusinessObjectTypeName);
            //Assert.AreEqual(dirtyXml, transactionLogEntry.DateTimeUpdated);
            Assert.AreEqual(userName, transactionLogEntry.LogonUser);
            Assert.AreEqual(Environment.MachineName, transactionLogEntry.MachineName);
            Assert.AreEqual(WindowsIdentity.GetCurrent().Name, transactionLogEntry.WindowsUser);
        }

        private static void SetupMockSecurityController(string userName)
        {
            ISecurityController securityController = MockRepository.GenerateStub<ISecurityController>();
            securityController.Stub(t => t.CurrentUserName).Return(userName);
            GlobalRegistry.SecurityController = securityController;
        }
    }

    /// <summary>
    /// This is a Transaction Logger that logs transactions using a BusinessObject.
    /// </summary>
    public class Transactionlogger : ITransactionLogger
    {
        public IBusinessObject GetCurrentDirtyTransactionLogEntry(IBusinessObject businessObject)
        {
            TransactionLogEntry transactionLogEntry = new TransactionLogEntry();
            string dirtyXml = ((BusinessObject) businessObject).DirtyXML;
            string userName = null;
            if (GlobalRegistry.SecurityController != null) userName = GlobalRegistry.SecurityController.CurrentUserName;
            transactionLogEntry.LogonUser = userName;
            transactionLogEntry.CRUDAction = "Added";
            transactionLogEntry.DirtyXML = new LongText(dirtyXml);
            transactionLogEntry.BusinessObjectToString = businessObject.ToString();
            transactionLogEntry.BusinessObjectTypeName = typeof (DMClass).ToString();
            //transactionLogEntry.DateTimeUpdated = ;
            transactionLogEntry.MachineName = Environment.MachineName;
            transactionLogEntry.WindowsUser = WindowsIdentity.GetCurrent().Name;
            return transactionLogEntry;
        }
    }

    public interface ITransactionLogger
    {
    }
}